﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Boggle.Net.Model;
using NUnit.Framework;

namespace Boggle.Net.Tests.Primitives
{
    [TestFixture]
    public class TrieTests
    {
        [Test, TestCaseSource("TestDataForContains")]
        public bool Contains(Trie trie, string word)
        {
            return trie.Contains(word);
        }

        [Test, TestCaseSource("TestDataForContainsPrefix")]
        public bool ContainsPrefix(Trie trie, string prefix)
        {
            return trie.ContainsPrefix(prefix);
        }

        [Test]
        public void EnumeratorShouldReturnExceptedWords()
        {
            var trie = new Trie(WordList);
            Assert.AreEqual(WordList.OrderBy(word => word), trie.OrderBy(word => word));
        }

        // ReSharper disable UnusedMember.Local

        private static IEnumerable<string> WordList
        {
            get
            {
                return new[]
                {
                    "the",
                    "these",
                    "their",
                    "thesis",
                    "apple",
                    "swan"
                };
            }
        }

        private static IEnumerable TestDataForContains
        {
            get
            {
                var trie = new Trie(WordList);

                yield return new TestCaseData(trie, null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData(trie, String.Empty).Returns(false);
                yield return new TestCaseData(trie, "cat").Returns(false);
                yield return new TestCaseData(trie, "The").Returns(false);
                yield return new TestCaseData(trie, "the").Returns(true);
                yield return new TestCaseData(trie, "these").Returns(true);
                yield return new TestCaseData(trie, "their").Returns(true);
                yield return new TestCaseData(trie, "theirs").Returns(false);
                yield return new TestCaseData(trie, "them").Returns(false);
                yield return new TestCaseData(trie, "th").Returns(false);
                yield return new TestCaseData(trie, "theyre").Returns(false);
            }
        }

        private static IEnumerable TestDataForContainsPrefix
        {
            get
            {
                var trie = new Trie(WordList);

                yield return new TestCaseData(trie, null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData(trie, String.Empty).Returns(false);
                yield return new TestCaseData(trie, "cat").Returns(false);
                yield return new TestCaseData(trie, "T").Returns(false);
                yield return new TestCaseData(trie, "th").Returns(true);
                yield return new TestCaseData(trie, "the").Returns(true);
                yield return new TestCaseData(trie, "thes").Returns(true);
                yield return new TestCaseData(trie, "this").Returns(false);
                yield return new TestCaseData(trie, "theyre").Returns(false);
                yield return new TestCaseData(trie, "theirs").Returns(false);
            }
        }

        // ReSharper restore UnusedMember.Local
    }
}
